// #pragma once
#ifndef THREAD_HPP
#define THREAD_HPP

#include <iostream>
#include <string>
#include <unistd.h>
#include <functional>
#include <pthread.h>
#include <vector>
#include <unistd.h>

// 封装线程
namespace MyThreadArea
{
    using func_t = std::function<void(std::string name)>;
    static int number = 1; // 线程的唯一编号
    enum STATUS
    {
        NEW,
        RUNNING,
        STOP
    };

    std::string ToHex(pthread_t num)
    {
        char buffer[64];
        snprintf(buffer, sizeof(buffer), "0x%lx", num);
        return buffer;
    }

    class Thread
    {
    private:
        static void *run(void *args) // 使用 static 时参数列表不再默认含有 this
        {
            Thread *th = static_cast<Thread *>(args);

            th->_status = STATUS::RUNNING;
            // if(!th->_join)  //启动分离
            //     th->EnableJoin();
            th->_func_t(th->GetName()); // 调用 _func_t 回调函数
            return nullptr;
        }

        void SetName()
        {
            _name = "Thread - " + std::to_string(number++);
        }

        void EnableDecatch() // 启用分离
        {
            _join = false;
        }

        void EnableJoin() // 禁用分离:可以等待
        {
            _join = true;
        }

    public:
        Thread(func_t func) : _status(STATUS::NEW), _join(true), _func_t(func)
        {
            _pid = getpid();
            SetName(); // 设置线程名
        }

        bool Start() // 创建进程
        {
            if (_status == STATUS::RUNNING)
                return true;
            int n = ::pthread_create(&_id, nullptr, run, this); // 创建线程执行 run，回调 _fun_t 函数
            if (n != 0)
            {
                std::cerr << "pthread_create error" << std::endl;
                return false;
            }
            return true;
        }

        bool StopPthread() // 停止线程
        {
            if (_status == STATUS::RUNNING)
            {
                int n = ::pthread_cancel(_id);
                if (n != 0)
                {
                    std::cerr << "pthread_cancel error" << std::endl;
                    return false;
                }
                _status = STATUS::STOP;
                return true;
            }
            return false;
        }

        bool Join() // 等待
        {
            if (_join)
            {
                int n = ::pthread_join(_id, nullptr);
                if (n != 0)
                {
                    std::cerr << "pthread_join error" << std::endl;
                    return false;
                }
                _status = STATUS::STOP;
                return true;
            }
            return false;
        }

        void Delete()
        {
            EnableDecatch();
            pthread_detach(_id);
        }

        bool IsJoin() { return _join; }
        std::string GetName() { return _name; }

        ~Thread()
        {
        }

    private:
        std::string _name;
        bool _join; // 是否分离, 是否可以被等待
        pid_t _pid;
        pthread_t _id;  // 线程id
        STATUS _status; // 线程状态
        func_t _func_t; // 回调函数
    };

    // std::string Name()
    // {
    //     Thread th;
    //     return th.GetName();
    // }
}

#endif